﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Niknak.Services.TaskScheduler.Interfaces;

namespace Niknak.Services.TaskScheduler.Processors
{
    public abstract class BaseProcessor<TaskType, ConfigType, AuditLogType, AuditLogEntryType> : ITaskProcessor<ConfigType, AuditLogType, AuditLogEntryType>
        where TaskType : IConfiguredTask<ConfigType>, IControlledTask, new()
        where ConfigType : new()
        where AuditLogType : Interfaces.DataModel.IAuditLog<AuditLogEntryType>, new()
        where AuditLogEntryType : Interfaces.DataModel.IAuditLogEntry
    {
        protected AuditLogType CurrentLog { get; set; }

        /// <summary>
        /// Returns the current UTC time without milliseconds
        /// </summary>
        public DateTime UtcNow
        {
            get
            {
                DateTime utcNow = DateTime.UtcNow;
                return new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, utcNow.Hour, utcNow.Minute, utcNow.Second, DateTimeKind.Utc);
            }
        }

        private TaskType _TaskInstance;
        public TaskType TaskInstance(ConfigType config)
        { 
            if (_TaskInstance == null)
            {
                _TaskInstance = new TaskType();
                _TaskInstance.LoadConfig(config);
            }
            return _TaskInstance;
        }

        public virtual void Processor_Load(string startArguments) {  }

        #region ITaskProcessor implementation

        public abstract Enums.TaskOutcome ProcessTask(ConfigType config, AuditLogType currentLog, ref bool terminate);

        public event EventHandler<ServiceCore.TaskScheduler.IterationEventArgs> TaskIterationStarting;
        public event EventHandler<ServiceCore.TaskScheduler.IterationEventArgs> TaskIterationTerminationRequest;
        public event EventHandler<ServiceCore.TaskScheduler.IterationEventArgs> TaskIterationCompleted;
        public event EventHandler TaskShuttingDown;
        public event EventHandler<ServiceCore.TaskScheduler.LoggingEventArgs> TaskLogMessageGenerated;

        public void RaiseTaskIterationStartingEvent(object sender, ServiceCore.TaskScheduler.IterationEventArgs eventArgs)
        {
            if (TaskIterationStarting != null)
                TaskIterationStarting(sender, eventArgs);
        }

        public void RaiseTaskIterationTerminationRequestEvent(object sender, ServiceCore.TaskScheduler.IterationEventArgs eventArgs)
        {
            if (TaskIterationTerminationRequest != null)
                TaskIterationTerminationRequest(sender, eventArgs);
        }

        public void RaiseTaskIterationCompletedEvent(object sender, ServiceCore.TaskScheduler.IterationEventArgs eventArgs)
        {
            if (TaskIterationCompleted != null)
                TaskIterationCompleted(sender, eventArgs);
        }

        public void RaiseTaskShuttingDownEvent(object sender, EventArgs eventArgs)
        {
            if (TaskShuttingDown != null)
                TaskShuttingDown(sender, eventArgs);
        }

        public void RaiseTaskLogMessageGeneratedEvent(object sender, ServiceCore.TaskScheduler.LoggingEventArgs eventArgs)
        {
            if (TaskLogMessageGenerated != null)
                TaskLogMessageGenerated(sender, eventArgs);
        }

        #endregion
    }
}
